package com.gjy.spring.record;

import com.gjy.spring.entity.AuditRecord;
import com.gjy.spring.repository.AuditRepository;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-03-03 19:27:34
 */
@Component
public class AuditRecorder {

    private static final long MAX_FLUSH_INTERVAL = 3000;
    private volatile long lastFlushTime = System.currentTimeMillis();
    private final BlockingQueue<AuditRecord> auditQueue = new LinkedBlockingQueue<>(1000);
    private final Executor executor = Executors.newSingleThreadExecutor();
    private final AuditRepository auditRepository;

    public AuditRecorder(AuditRepository auditRepository) {
        this.auditRepository = auditRepository;
        startConsumer();
    }

    public void record(AuditRecord record) {
        if (!auditQueue.offer(record)) {
            System.err.println("审计队列已满，记录被丢弃: " + record);
        }
    }

    private void startConsumer() {
        executor.execute(() -> {
            List<AuditRecord> buffer = new ArrayList<>(100);
            while (!Thread.interrupted()) {
                try {
                    AuditRecord record = auditQueue.poll(MAX_FLUSH_INTERVAL, TimeUnit.MILLISECONDS);
                    if (record != null) {
                        buffer.add(record);
                    }
                    if (buffer.size() >= 100 || System.currentTimeMillis() - lastFlushTime > MAX_FLUSH_INTERVAL) {
                        if (!buffer.isEmpty()) {
                            auditRepository.saveAll(buffer);
                            buffer.clear();
                            lastFlushTime = System.currentTimeMillis();
                        }
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
    }

}
